import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() => runApp(RootApp());

class RootApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // 使用getX第一步
    return MaterialApp(
      title: 'Provider学习',
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage>
    with TickerProviderStateMixin, WidgetsBindingObserver {
  // TickerProviderStateMixin 是为了使用vys.. 的this
  // WidgetsBindingObserver 创建监听
  // ---------全局变量----------//
  // 手机号焦点控制 用户控制输入是，焦点的聚焦和控制焦点失去焦点
  FocusNode userPhoneFieldNode = new FocusNode();
  // 用户名密码 焦点控制
  FocusNode userPasswordFieldNode = new FocusNode();

  // 输入框textfield控制 用于控制输入框的控制器 可以获取值，判断值 以及其他特效
  TextEditingController _userPhoneTextController;
  TextEditingController _userPasswordTextController;

  // 错误表示 如果是ture，就给输入框添加抖动动画
  bool isPhoneError = false;
  bool isPasswordError = false;

  // 正在输入TextField的边框颜色
  Color selectColor = Colors.green;
  // 未在输入TextField的边框颜色
  Color normalColor = Color(0x88fafafa);
  // 复选框标识
  bool checkIsChecked = false;

  // RickText中的注册协议手势 richtext手势识别器 可识别点击的是哪个
  TapGestureRecognizer _registProtocolRecognizer;
  // RickText中的隐私协议手势
  TapGestureRecognizer __privacyProtocolRecognizer;

  // 注册动画控制器
  AnimationController registerAnimatController;

  // logo动画控制器
  AnimationController logoAnimatController;
  Animation logoAnimation;

  // 输入框动画控制器 抖动动画
  AnimationController inputAnimatController;
  Animation inputAnimation;

  // 抖动动画执行次数
  int inputAnimationNumber = 0;

// ---------------------------//
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    // 初始化输入框文本编辑控制器
    _userPhoneTextController = new TextEditingController();
    _userPasswordTextController = new TextEditingController();
    // 初始化 手势事件
    _registProtocolRecognizer = new TapGestureRecognizer();
    __privacyProtocolRecognizer = new TapGestureRecognizer();
    // 输入框监听事件
    userPhoneFieldNode.addListener(() {
      setState(() {});
    });
    userPasswordFieldNode.addListener(() {
      setState(() {});
    });

    // 动画抖动控制器注册
    registerAnimatController =
        new AnimationController(duration: Duration(seconds: 4), vsync: this);
    registerAnimatController.addListener(() {
      double value = registerAnimatController.value;
      // 注册变化比率
      print("注册变化比率 $value");
      setState(() {});
    });

    logoAnimatController = new AnimationController(
        duration: Duration(milliseconds: 400), vsync: this);
    logoAnimatController.addListener(() {
      setState(() {});
    });

    logoAnimation = Tween(begin: 1.0, end: 0.0).animate(logoAnimatController);

// 添加监听
    WidgetsBinding.instance.addObserver(this);

    // 左右摆动两次 实现抖动动画
    inputAnimatController = new AnimationController(
        duration: Duration(milliseconds: 100), vsync: this);

    inputAnimation =
        Tween(begin: 1.0, end: 10.0).animate(inputAnimatController);
    inputAnimatController.addListener(() {
      double value = inputAnimatController.value;
      // 注册变化比率
      print("输入框变化比率 $value");
      setState(() {});
      setState(() {});
    });

    // 输入框添加动画监听
    inputAnimatController.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        print("动画正向执行完成 调用forward方法动画执行完毕的回调");
        inputAnimationNumber++;
        // 执行反向动画
        inputAnimatController.reverse();
      } else if (status == AnimationStatus.dismissed) {
        print("动画反向执行完成 调用reverse方法动画执行完毕的回调");
        // 重置动画
        inputAnimatController.reset();
        // 记录动画的执行次数
        // 执行两次，变达到左右抖动的效果
        if (inputAnimationNumber < 2) {
          inputAnimatController.forward();
        } else {
          inputAnimationNumber = 0;
        }
      }
      //
    });
  }

  @override
  void dispose() {
    super.dispose();
    // 解绑
    WidgetsBinding.instance.removeObserver(this);
  }

  //应用尺寸改变时回调
  @override
  void didChangeMetrics() {
    super.didChangeMetrics();

    /*
     *Frame是一次绘制过程，称其为一帧，Flutter engine受显示器垂直同步信号"VSync"的驱使不断的触发绘制，
     *Flutter可以实现60fps（Frame Per-Second），就是指一秒钟可以触发60次重绘，FPS值越大，界面就越流畅。
     */
    WidgetsBinding.instance.addPostFrameCallback((_) {
      //注意，不要在此类回调中再触发新的Frame，这可以会导致循环刷新。
      setState(() {
        ///获取底部遮挡区域的高度
        double keyboderFlexHeight = MediaQuery.of(context).viewInsets.bottom;
        print("键盘的高度 keyboderFlexHeight $keyboderFlexHeight");
        if (MediaQuery.of(context).viewInsets.bottom == 0) {
          //关闭键盘 启动logo动画反向执行 0.0 -1.0
          // logo 布局区域显示出来
          logoAnimatController.reverse();
        } else {
          //显示键盘 启动logo动画正向执行 1.0-0.0
          // logo布局区域缩放隐藏
          logoAnimatController.forward();
        }
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // 阻止界面resize
      resizeToAvoidBottomInset: false,
      // 全局的手势
      body: GestureDetector(
        onTap: () {
          // 键盘隐藏
          SystemChannels.textInput.invokeMethod("TextInput.hide");
          // 输入框失去焦点
          userPhoneFieldNode.unfocus();
          userPasswordFieldNode.unfocus();
        },
        child: Stack(
          children: [
            // 构建背景
            buildBgWidget(),
            // 构建阴影层
            buildBlurWidget(),
            // 构建用户输入框
            buildLoginInputWidget(),
          ],
        ),
      ),
    );
  }

  Widget buildBgWidget() {
    return Positioned(
      top: 0,
      bottom: 0,
      left: 0,
      right: 0,
      child: Image.asset("images/bg_kyzg_login2.png", fit: BoxFit.fill),
    );
  }

  Widget buildBlurWidget() {
    return Container(
      color: Color.fromARGB(150, 100, 100, 100),
    );
  }

  Widget buildLoginInputWidget() {
    // 填充
    return Positioned(
      top: 0,
      bottom: 0,
      left: 0,
      right: 0,
      child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Column(
          children: [
            // 顶部距离
            // SizedBox(height: 100), 不用box的原因是背景会被box占用
            Container(
              margin: EdgeInsets.only(top: 100.0, left: 22, right: 22),
            ),
            // logo+应用名称
            buildLoginWidget(),
            SizedBox(height: 30),
            // 手机输入框
            buildUserRowWidget(Icons.phone_android, '请输入11位手机号码',
                userPhoneFieldNode, _userPhoneTextController, isPhoneError),
            SizedBox(height: 30),
            // 密码输入框
            buildUserRowWidget(
                Icons.lock_open,
                '请输入4-6位密码',
                userPasswordFieldNode,
                _userPasswordTextController,
                isPasswordError),
            // 构建用户协议
            buildAgreementWidget(),
            SizedBox(height: 50),
            // 注册按钮
            buildRegisterButton(),
          ],
        ),
      ),
    );
  }

  // 构建顶部的logo
  buildLoginWidget() {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Padding(
          padding: EdgeInsets.only(right: 14),
          child: ClipRRect(
            borderRadius: BorderRadius.all(
              Radius.circular(8),
            ),
            child: Image.asset("images/logo.jpg", width: 44, height: 44),
          ),
        ),
        Text(
          "GGB",
          style: TextStyle(
            color: Colors.white,
            fontSize: 20,
            fontFamily: "abc",
          ),
        ),
      ],
    );
  }

  buildUserRowWidget(IconData preIcon, String hintText, FocusNode focusNode,
      TextEditingController controller, bool isError) {
    return Transform.translate(
      offset: Offset(isError ? inputAnimation.value : 0, 0),
      child: Container(
          margin: EdgeInsets.only(left: 22, right: 22),
          decoration: BoxDecoration(
            color: Color(0x88fafafa),
            borderRadius: BorderRadius.all(Radius.circular(30)),
            border: Border.all(
                color: focusNode.hasFocus ? selectColor : normalColor),
          ),
          child: buildInputItemRow(preIcon, hintText, focusNode, controller)),
    );
  }

  buildInputItemRow(
    IconData preIcon,
    String hintText,
    FocusNode focusNode,
    TextEditingController controller,
  ) {
    return Row(children: [
      // 左侧小图标
      Padding(
        padding: EdgeInsets.only(left: 10),
        child: Icon(
          // Icons.phone_android,
          preIcon,
          color: Color(0xaafafafa),
          size: 26,
        ),
      ),
      // 竖线
      Padding(
        padding: EdgeInsets.all(10),
        child: Container(
          width: 1,
          height: 26,
          color: Color(0xaafafafa),
        ),
      ),
      // 输入框
      Expanded(
        child: TextField(
          controller: controller,
          focusNode: focusNode,
          onSubmitted: (value) {
            print("$value");
            // 电话失去焦点
            userPasswordFieldNode.unfocus();
            // 密码输入 获取焦点
            FocusScope.of(context).requestFocus(userPasswordFieldNode);
          },
          // 键盘回车的样式
          textInputAction: TextInputAction.next,
          // 输入文本格式过滤
          inputFormatters: [
            // 输入的内容长度为11位
            LengthLimitingTextInputFormatter(11),
          ],
          // 设置键盘的类型
          keyboardType: TextInputType.text,
          // 输入文本样式
          style: TextStyle(fontSize: 16.0, color: Colors.white),
          // 边框样式
          decoration: InputDecoration(
            hintText: hintText,
            hintStyle: TextStyle(color: Color(0xaafafafa)),
            border: InputBorder.none,
          ),
        ),
        // 清楚选项
      ),
      InkWell(
        onTap: () {
          if (controller.text != '') {
            controller.text = '';
          }
        },
        child: focusNode.hasFocus
            ? Container(
                margin: EdgeInsets.only(left: 10, right: 12),
                child: Icon(Icons.close),
              )
            : Container(),
      ),
    ]);
  }

  // 构建用户协议
  buildAgreementWidget() {
    return Container(
      margin: EdgeInsets.only(left: 22, right: 22, top: 10),
      child: Row(
        children: [
          buildCircleCheckBox(),
          // 文字区域
          Expanded(
            child: buildRichText(),
          ),
        ],
      ),
    );
  }
  // 自定义复选框

  buildCircleCheckBox() {
    return Container(
      margin: EdgeInsets.all(8),
      child: InkWell(
        // 点击事件响应范围
        borderRadius: BorderRadius.all(
          Radius.circular(30),
        ),
        onTap: () {
          setState(() {
            checkIsChecked = !checkIsChecked;
          });
        },
        child: ClipOval(
          child: Image.asset(
              checkIsChecked
                  ? "images/select_icon.png"
                  : "images/no_select_icon.png",
              width: 18,
              height: 18),
        ),
      ),
    );
  }

  RichText buildRichText() {
    return RichText(
      text: TextSpan(
        text: "注册同意",
        style: TextStyle(color: Colors.grey),
        children: [
          TextSpan(
            text: '《用户注册协议》',
            style: TextStyle(
              color: Colors.blue,
            ),
            recognizer: _registProtocolRecognizer
              ..onTap = () {
                print("点击了用户协议");
              },
          ),
          TextSpan(
            text: '与',
            style: TextStyle(
              color: Color(0xaafafafa),
            ),
          ),
          TextSpan(
            text: '《隐私协议》',
            style: TextStyle(color: Colors.blue),
            recognizer: __privacyProtocolRecognizer
              ..onTap = () {
                print("点击了隐私协议");
              },
          ),
        ],
      ),
    );
  }

  // 注册按钮
  buildRegisterButton() {
    return InkWell(
      onTap: () {
        userPasswordFieldNode.unfocus();
        userPhoneFieldNode.unfocus();

        // 参数验证
        // 获取输入的电话号码
        String inputPhone = _userPhoneTextController.text;
        if (inputPhone.length != 11) {
          // 更新标识 触发抖动动画
          isPhoneError = true;
          inputAnimatController.forward();
          return;
        } else {
          isPhoneError = false;
        }

        // 获取输入的密码
        String inputPassword = _userPasswordTextController.text;
        if (inputPassword.length < 6) {
          // 更新标识 触发抖动动画
          isPasswordError = true;
          inputAnimatController.forward();
          return;
        } else {
          isPasswordError = false;
        }

        // 提交数据
        registerAnimatController.forward();
        Future.delayed(Duration(milliseconds: 8000), () {
          // 模拟失败
          // currentRestureStatus=RestureStatus.error;
          // setState(() {

          // });
          //  Future.delayed(Duration(milliseconds: 2000),(){
          //     //
          //  registerAnimatController.forward();
          //   });

          // currentRestureStatus = RestureStatus.success;
          // setState(() {

          // });
        });
        //  Future.delayed(Duration(milliseconds: 2000),(){
        //     // 跳转首页面
        //   });
      },
      child: Stack(
        children: [
          ///缩放变换
          Transform(
              alignment: Alignment.center,
              transform: Matrix4.diagonal3Values(
                  1.0 - registerAnimatController.value, 1.0, 1.0),
              child: Container(
                alignment: Alignment.center,
                width: MediaQuery.of(context).size.width,
                height: 48,
                margin: EdgeInsets.only(
                  left: 22,
                  right: 22,
                ),

                ///圆角矩形背景
                decoration: BoxDecoration(
                    color: Color(0x50fafafa),
                    borderRadius: BorderRadius.all(Radius.circular(30)),
                    border: Border.all(color: normalColor)),

                ///透明度
                child: Text(
                  "注册",
                  style: TextStyle(
                      fontSize: 18,
                      color: Colors.white,
                      fontWeight: FontWeight.w500),
                ),
              )),

          ///进度圆圈
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              ///透明度
              Opacity(
                ///中间显示的Widget透明度
                opacity: registerAnimatController.value,
                child: Container(
                    height: 48.0,
                    width: 48.0,
                    padding: EdgeInsets.all(10),

                    ///根据不同状态来修改不同的注册中间的显示Widget
                    child: buildLoadingWidget(),
                    decoration: BoxDecoration(
                      color: Color(0x50fafafa),
                      borderRadius: BorderRadius.all(Radius.circular(30)),
                    )),
              ),
            ],
          ),
        ],
      ),
    );
  }

  RestureStatus currentRestureStatus = RestureStatus.none;

  ///动态构建不同的显示进度圆圈
  /// 加载中、加载错误、加载成功
  Widget buildLoadingWidget() {
    ///默认使用加载中
    Widget loadingWidget = CircularProgressIndicator();
    if (currentRestureStatus == RestureStatus.success) {
      ///加载成功显示小对钩
      loadingWidget = Icon(
        Icons.check,
        color: Colors.deepOrangeAccent,
      );
    } else if (currentRestureStatus == RestureStatus.error) {
      ///加载失败状态显示 小X
      loadingWidget = Icon(
        Icons.close,
        color: Colors.red,
      );
    }
    return loadingWidget;
  }
}

enum RestureStatus {
  none, //无状态
  loading, //加载中
  success, //加载成功
  error, //加载失败
  rever, //重试
}
